package es.silenus.detecta.util;

import org.apache.commons.codec.BinaryEncoder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.io.UnsupportedEncodingException;

/**
 * Password encoder.
 *
 * @author Mariano Alonso
 * @since 15-oct-2009 11:18:49
 */
public class PasswordEncoder {


	private byte[] digest(final String algorithm,
												final String charset,
												final String input) {
		try {
			MessageDigest digester = MessageDigest.getInstance(algorithm);
			return digester.digest(input.getBytes(charset));
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException(e.getMessage(), e);
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}


	/**
	 *
	 *
	 * @param encoderClass
	 * @param encoderCharset
	 * @param digestAlgorithm
	 * @param digestCharset
	 * @param password
	 * @return
	 */
	public String encodePassword(final String encoderClass,
															 final String encoderCharset,
															 final String digestAlgorithm,
															 final String digestCharset,
															 final String password) {



		byte[] digestedPassword = digest(digestAlgorithm, digestCharset, password);


		byte[] encodedPassword = null;

		BinaryEncoder encoder = null;
		try {
			encoder = (BinaryEncoder)Class.forName(encoderClass).newInstance();
			encodedPassword = encoder.encode(digestedPassword);
		} catch (Throwable e) {
			throw new RuntimeException(e.getMessage(), e);
		}


		String result = null;

		try {
			result = new String(encodedPassword, encoderCharset);
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e.getMessage(), e);
		}

		return result;
	}


	public static void main(String[] args) {
		if(args.length != 5) {
			System.out.println("Usage: PasswordEncoder <encoder_class_name> <encoder_charset> <digest_algorithm> <digest_charset> <password>");
			System.out.println("Example: PasswordEncoder org.apache.commons.codec.binary.Base64  UTF-8  MD4  UnicodeLittleUnmarked <password>");
			System.out.println("Example: PasswordEncoder org.apache.commons.codec.binary.Hex  UTF-8  MD4  UnicodeLittleUnmarked <password>");
			System.exit(1);
		}

		// Add provider
		Security.addProvider(new BouncyCastleProvider());

		PasswordEncoder encoder = new PasswordEncoder();

		String result = encoder.encodePassword(args[0], args[1], args[2], args[3], args[4]);

		System.out.println(String.format("%s\t%s", args[4], result));

	}

}
